#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
HAI优化系统API接口
提供REST API接口，与现有系统集成
"""

import json
import logging
from flask import Flask, request, jsonify, Response, redirect
from typing import Dict, Any, Optional
import time

# 先加载环境变量
import os
from dotenv import load_dotenv

# 加载环境变量
load_dotenv()

from core.hai_optimization_controller import get_controller
from core.user_identification import get_client_ip
from config.config import CONFIG

logger = logging.getLogger(__name__)

# 创建Flask应用
app = Flask(__name__)

# 获取控制器实例
controller = get_controller()

# 自动启动HAI优化系统将在Flask应用启动后进行


@app.before_request
def before_request():
    """请求前处理"""
    # 自动启动HAI优化系统（只在第一次请求时启动）
    if not controller.running:
        logger.info("自动启动HAI优化系统...")
        try:
            controller.start()
            logger.info("HAI优化系统启动成功")
        except Exception as e:
            logger.error(f"HAI优化系统启动失败: {e}")
    
    # 记录请求日志
    logger.info(f"API请求: {request.method} {request.path} from {request.remote_addr}")


@app.after_request
def after_request(response):
    """请求后处理"""
    # 添加CORS头
    response.headers['Access-Control-Allow-Origin'] = '*'
    response.headers['Access-Control-Allow-Methods'] = 'GET, POST, PUT, DELETE, OPTIONS'
    response.headers['Access-Control-Allow-Headers'] = 'Content-Type, Authorization'
    return response


@app.route('/api/v1/system/status', methods=['GET'])
def get_system_status():
    """获取系统状态"""
    try:
        status = controller.get_system_status()
        return jsonify({
            "success": True,
            "data": status
        })
    except Exception as e:
        logger.error(f"获取系统状态失败: {e}")
        return jsonify({
            "success": False,
            "error": str(e)
        }), 500


@app.route('/api/v1/system/start', methods=['POST'])
def start_system():
    """启动系统"""
    try:
        success = controller.start()
        return jsonify({
            "success": success,
            "message": "系统启动成功" if success else "系统启动失败"
        })
    except Exception as e:
        logger.error(f"启动系统失败: {e}")
        return jsonify({
            "success": False,
            "error": str(e)
        }), 500


@app.route('/api/v1/system/stop', methods=['POST'])
def stop_system():
    """停止系统"""
    try:
        controller.stop()
        return jsonify({
            "success": True,
            "message": "系统已停止"
        })
    except Exception as e:
        logger.error(f"停止系统失败: {e}")
        return jsonify({
            "success": False,
            "error": str(e)
        }), 500


@app.route('/api/v1/sessions/cancel', methods=['POST'])
def cancel_session_tasks():
    """取消会话的所有任务"""
    try:
        data = request.get_json()
        
        if not data:
            return jsonify({
                "success": False,
                "error": "请求数据为空"
            }), 400
        
        session_id = data.get('session_id')
        if not session_id:
            return jsonify({
                "success": False,
                "error": "缺少会话ID"
            }), 400
        
        # 调用控制器取消会话任务
        result = controller.cancel_session_tasks(session_id)
        
        return jsonify(result)
        
    except Exception as e:
        logger.error(f"取消会话任务失败: {e}")
        return jsonify({
            "success": False,
            "error": str(e)
        }), 500


@app.route('/api/v1/gateway/status', methods=['GET'])
def get_gateway_registration_status():
    """获取API网关注册状态"""
    try:
        status = api_gateway_registry.get_registration_status()
        return jsonify({
            "success": True,
            "data": status
        })
    except Exception as e:
        logger.error(f"获取API网关注册状态失败: {e}")
        return jsonify({
            "success": False,
            "error": str(e)
        }), 500


@app.route('/api/v1/tasks/submit', methods=['POST'])
def submit_task():
    """提交任务"""
    try:
        data = request.get_json()
        
        if not data:
            return jsonify({
                "success": False,
                "error": "请求数据为空"
            }), 400
        
        task_id = data.get('task_id')
        task_data = data.get('task_data', {})
        session_id = data.get('session_id')  # 获取会话ID
        
        if not task_id:
            return jsonify({
                "success": False,
                "error": "任务ID不能为空"
            }), 400
        
        # 获取客户端IP
        client_ip = get_client_ip(request)
        
        # 提交任务（包含会话ID）
        result = controller.submit_task(task_id, client_ip, task_data, session_id)
        
        return jsonify(result)
        
    except Exception as e:
        logger.error(f"提交任务失败: {e}")
        return jsonify({
            "success": False,
            "error": str(e)
        }), 500


@app.route('/api/v1/enhance', methods=['POST'])
def enhance_image():
    """
    图片增强API - 兼容API网关的接口格式
    自动提交任务到HAI优化系统，触发扩缩容
    """
    try:
        logger.info("收到图片增强请求")
        
        # 检查是否有文件上传
        if 'file' not in request.files:
            return jsonify({
                "success": False,
                "error": "没有上传文件"
            }), 400
        
        file = request.files['file']
        if file.filename == '':
            return jsonify({
                "success": False,
                "error": "文件名为空"
            }), 400
        
        # 获取其他参数
        tile_size = request.form.get('tile_size', '400')
        quality_level = request.form.get('quality_level', 'high')
        
        # 生成任务ID
        import uuid
        task_id = f"task_{uuid.uuid4().hex[:16]}"
        
        # 读取文件内容
        file_content = file.read()
        file_size = len(file_content)
        file.seek(0)  # 重置文件指针
        
        # 准备任务数据
        task_data = {
            'file_name': file.filename,
            'file_size': file_size,
            'tile_size': tile_size,
            'quality_level': quality_level,
            'timestamp': time.time()
        }
        
        # 获取客户端IP
        client_ip = get_client_ip(request)
        
        logger.info(f"提交图片增强任务: {task_id}, 文件: {file.filename}, 大小: {file_size} bytes, IP: {client_ip}")
        
        # 提交任务到HAI优化系统
        result = controller.submit_task(task_id, client_ip, task_data)
        
        if result.get('success'):
            return jsonify({
                "task_id": task_id,
                "status": "queued",
                "message": "任务已提交，正在排队处理",
                "queue_position": result.get('queue_position', 0)
            })
        else:
            return jsonify({
                "success": False,
                "error": result.get('message', '提交任务失败')
            }), 500
        
    except Exception as e:
        logger.error(f"处理图片增强请求失败: {e}")
        return jsonify({
            "success": False,
            "error": str(e)
        }), 500


@app.route('/api/v1/tasks/<task_id>/status', methods=['GET'])
def get_task_status(task_id):
    """获取任务状态"""
    try:
        status = controller.get_task_status(task_id)
        return jsonify({
            "success": True,
            "data": status
        })
    except Exception as e:
        logger.error(f"获取任务状态失败: {e}")
        return jsonify({
            "success": False,
            "error": str(e)
        }), 500


@app.route('/api/v1/status/<task_id>', methods=['GET'])
def get_task_status_legacy(task_id):
    """获取任务状态（兼容性端点）"""
    try:
        status = controller.get_task_status(task_id)
        return jsonify({
            "success": True,
            "data": status
        })
    except Exception as e:
        logger.error(f"获取任务状态失败: {e}")
        return jsonify({
            "success": False,
            "error": str(e)
        }), 500


@app.route('/api/v1/download/<task_id>', methods=['GET'])
def download_task_result(task_id):
    """下载任务结果 - 直接返回图片文件"""
    try:
        logger.info(f"收到下载请求: {task_id}")
        
        # 获取任务状态
        status = controller.get_task_status(task_id)
        
        # 如果任务未完成，返回错误
        if status.get('status') != 'completed':
            return jsonify({
                "success": False,
                "error": "任务未完成"
            }), 400
        
        # 获取任务结果文件路径
        result = controller.get_task_result(task_id)
        if not result or 'file_path' not in result:
            return jsonify({
                "success": False,
                "error": "任务结果文件不存在"
            }), 404
        
        file_path = result['file_path']
        if not os.path.exists(file_path):
            logger.error(f"文件不存在: {file_path}")
            return jsonify({
                "success": False,
                "error": "文件不存在"
            }), 404
        
        # 直接返回图片文件
        from flask import send_file
        return send_file(
            file_path,
            mimetype='image/jpeg',
            as_attachment=True,
            download_name=f'enhanced_{task_id}.jpg'
        )
        
    except Exception as e:
        logger.error(f"下载任务结果失败: {e}")
        return jsonify({
            "success": False,
            "error": str(e)
        }), 500


@app.route('/api/v1/queue/status', methods=['GET'])
def get_queue_status():
    """获取队列状态"""
    try:
        status = controller.get_queue_status()
        return jsonify({
            "success": True,
            "data": status
        })
    except Exception as e:
        logger.error(f"获取队列状态失败: {e}")
        return jsonify({
            "success": False,
            "error": str(e)
        }), 500


@app.route('/api/v1/users/statistics', methods=['GET'])
def get_user_statistics():
    """获取用户统计"""
    try:
        stats = controller.get_user_statistics()
        return jsonify({
            "success": True,
            "data": stats
        })
    except Exception as e:
        logger.error(f"获取用户统计失败: {e}")
        return jsonify({
            "success": False,
            "error": str(e)
        }), 500


@app.route('/api/v1/servers', methods=['GET'])
def get_servers():
    """获取服务器列表"""
    try:
        region = request.args.get('region')
        status = request.args.get('status')
        
        servers = controller.get_server_list(region=region, status=status)
        
        return jsonify({
            "success": True,
            "data": servers
        })
    except Exception as e:
        logger.error(f"获取服务器列表失败: {e}")
        return jsonify({
            "success": False,
            "error": str(e)
        }), 500


@app.route('/api/v1/servers', methods=['POST'])
def create_server():
    """创建服务器"""
    try:
        data = request.get_json()
        
        if not data:
            return jsonify({
                "success": False,
                "error": "请求数据为空"
            }), 400
        
        region = data.get('region')
        gpu_type = data.get('gpu_type')
        
        result = controller.create_server(region=region, gpu_type=gpu_type)
        
        return jsonify(result)
        
    except Exception as e:
        logger.error(f"创建服务器失败: {e}")
        return jsonify({
            "success": False,
            "error": str(e)
        }), 500


@app.route('/api/v1/servers/<instance_id>', methods=['DELETE'])
def destroy_server(instance_id):
    """销毁服务器"""
    try:
        result = controller.destroy_server(instance_id)
        return jsonify(result)
    except Exception as e:
        logger.error(f"销毁服务器失败: {e}")
        return jsonify({
            "success": False,
            "error": str(e)
        }), 500


@app.route('/api/v1/reports/daily', methods=['GET'])
def get_daily_report():
    """获取每日报告"""
    try:
        date = request.args.get('date')
        report = controller.get_daily_report(date=date)
        
        return jsonify({
            "success": True,
            "data": report
        })
    except Exception as e:
        logger.error(f"获取每日报告失败: {e}")
        return jsonify({
            "success": False,
            "error": str(e)
        }), 500


@app.route('/api/v1/reports/weekly', methods=['GET'])
def get_weekly_report():
    """获取每周报告"""
    try:
        week_start_date = request.args.get('week_start_date')
        report = controller.get_weekly_report(week_start_date=week_start_date)
        
        return jsonify({
            "success": True,
            "data": report
        })
    except Exception as e:
        logger.error(f"获取每周报告失败: {e}")
        return jsonify({
            "success": False,
            "error": str(e)
        }), 500


@app.route('/api/v1/reports/monthly', methods=['GET'])
def get_monthly_report():
    """获取每月报告"""
    try:
        month = request.args.get('month')
        report = controller.get_monthly_report(month=month)
        
        return jsonify({
            "success": True,
            "data": report
        })
    except Exception as e:
        logger.error(f"获取每月报告失败: {e}")
        return jsonify({
            "success": False,
            "error": str(e)
        }), 500


@app.route('/api/v1/traffic/status', methods=['GET'])
def get_traffic_status():
    """获取流量状态"""
    try:
        status = controller.get_traffic_status()
        return jsonify({
            "success": True,
            "data": status
        })
    except Exception as e:
        logger.error(f"获取流量状态失败: {e}")
        return jsonify({
            "success": False,
            "error": str(e)
        }), 500


@app.route('/api/v1/cost/status', methods=['GET'])
def get_cost_status():
    """获取成本状态"""
    try:
        status = controller.get_cost_status()
        return jsonify({
            "success": True,
            "data": status
        })
    except Exception as e:
        logger.error(f"获取成本状态失败: {e}")
        return jsonify({
            "success": False,
            "error": str(e)
        }), 500


@app.route('/api/v1/servers/sync', methods=['POST'])
def sync_servers():
    """手动同步服务器列表"""
    try:
        result = controller.server_sync_manager.force_sync_now()
        
        return jsonify({
            "success": result.sync_success,
            "data": {
                "added_servers": result.added_servers,
                "removed_servers": result.removed_servers,
                "updated_servers": result.updated_servers,
                "sync_time": time.time()
            },
            "error": result.error_message
        })
    except Exception as e:
        logger.error(f"同步服务器失败: {e}")
        return jsonify({
            "success": False,
            "error": str(e)
        }), 500


@app.route('/api/v1/servers/sync/status', methods=['GET'])
def get_sync_status():
    """获取服务器同步状态"""
    try:
        status = controller.server_sync_manager.get_sync_status()
        return jsonify({
            "success": True,
            "data": status
        })
    except Exception as e:
        logger.error(f"获取同步状态失败: {e}")
        return jsonify({
            "success": False,
            "error": str(e)
        }), 500


@app.route('/api/v1/cost/optimize', methods=['POST'])
def optimize_costs():
    """执行成本优化"""
    try:
        results = controller.optimize_costs()
        return jsonify({
            "success": True,
            "data": results
        })
    except Exception as e:
        logger.error(f"执行成本优化失败: {e}")
        return jsonify({
            "success": False,
            "error": str(e)
        }), 500


@app.route('/api/v1/health/status', methods=['GET'])
def get_health_status():
    """获取健康状态"""
    try:
        status = controller.get_health_status()
        return jsonify({
            "success": True,
            "data": status
        })
    except Exception as e:
        logger.error(f"获取健康状态失败: {e}")
        return jsonify({
            "success": False,
            "error": str(e)
        }), 500


@app.route('/api/v1/faults', methods=['GET'])
def get_fault_events():
    """获取故障事件"""
    try:
        limit = request.args.get('limit', 10, type=int)
        events = controller.get_fault_events(limit=limit)
        return jsonify({
            "success": True,
            "data": events
        })
    except Exception as e:
        logger.error(f"获取故障事件失败: {e}")
        return jsonify({
            "success": False,
            "error": str(e)
        }), 500


@app.route('/api/v1/faults/<fault_id>/resolve', methods=['POST'])
def resolve_fault(fault_id):
    """解决故障"""
    try:
        success = controller.resolve_fault(fault_id)
        return jsonify({
            "success": success,
            "message": "故障已解决" if success else "故障解决失败"
        })
    except Exception as e:
        logger.error(f"解决故障失败: {e}")
        return jsonify({
            "success": False,
            "error": str(e)
        }), 500


@app.route('/api/v1/fault-tolerance/status', methods=['GET'])
def get_fault_tolerance_status():
    """获取故障转移状态"""
    try:
        status = controller.get_fault_tolerance_status()
        return jsonify({
            "success": True,
            "data": status
        })
    except Exception as e:
        logger.error(f"获取故障转移状态失败: {e}")
        return jsonify({
            "success": False,
            "error": str(e)
        }), 500


@app.route('/api/v1/real-apps/status', methods=['GET'])
def get_real_apps_status():
    """获取真实应用状态"""
    try:
        status = controller.get_real_apps_status()
        return jsonify({
            "success": True,
            "data": status
        })
    except Exception as e:
        logger.error(f"获取真实应用状态失败: {e}")
        return jsonify({
            "success": False,
            "error": str(e)
        }), 500


@app.route('/api/v1/real-apps/<app_id>/task', methods=['POST'])
def send_task_to_app(app_id):
    """向指定应用发送任务"""
    try:
        data = request.get_json()
        
        if not data:
            return jsonify({
                "success": False,
                "error": "请求数据为空"
            }), 400
        
        result = controller.send_task_to_app(app_id, data)
        
        return jsonify({
            "success": True,
            "data": result
        })
    except Exception as e:
        logger.error(f"向应用发送任务失败: {e}")
        return jsonify({
            "success": False,
            "error": str(e)
        }), 500


@app.route('/api/v1/real-apps/next', methods=['GET'])
def get_next_available_app():
    """获取下一个可用应用"""
    try:
        current_app_id = request.args.get('current_app_id')
        app_id = controller.get_next_available_app(current_app_id)
        
        if app_id:
            return jsonify({
                "success": True,
                "data": {
                    "app_id": app_id,
                    "message": f"下一个可用应用: {app_id}"
                }
            })
        else:
            return jsonify({
                "success": False,
                "error": "没有可用的应用"
            }), 404
    except Exception as e:
        logger.error(f"获取下一个可用应用失败: {e}")
        return jsonify({
            "success": False,
            "error": str(e)
        }), 500


@app.route('/api/v1/system/cleanup', methods=['POST'])
def cleanup_system():
    """清理系统数据"""
    try:
        result = controller.cleanup_expired_data()
        return jsonify({
            "success": True,
            "data": result
        })
    except Exception as e:
        logger.error(f"清理系统数据失败: {e}")
        return jsonify({
            "success": False,
            "error": str(e)
        }), 500


@app.route('/api/v1/config', methods=['GET'])
def get_config():
    """获取配置"""
    try:
        section = request.args.get('section')
        config_data = controller.get_config(section=section)
        
        return jsonify({
            "success": True,
            "data": config_data
        })
    except Exception as e:
        logger.error(f"获取配置失败: {e}")
        return jsonify({
            "success": False,
            "error": str(e)
        }), 500


@app.route('/api/v1/config', methods=['PUT'])
def update_config():
    """更新配置"""
    try:
        data = request.get_json()
        
        if not data:
            return jsonify({
                "success": False,
                "error": "请求数据为空"
            }), 400
        
        section = data.get('section')
        key = data.get('key')
        value = data.get('value')
        
        if not all([section, key, value is not None]):
            return jsonify({
                "success": False,
                "error": "section、key和value不能为空"
            }), 400
        
        result = controller.update_config(section, key, value)
        return jsonify(result)
        
    except Exception as e:
        logger.error(f"更新配置失败: {e}")
        return jsonify({
            "success": False,
            "error": str(e)
        }), 500


@app.route('/api/v1/health', methods=['GET'])
def health_check():
    """健康检查"""
    try:
        status = controller.get_system_status()
        
        return jsonify({
            "status": "healthy" if status.get('system', {}).get('running') else "unhealthy",
            "timestamp": time.time(),
            "uptime": status.get('system', {}).get('uptime', 0)
        })
    except Exception as e:
        logger.error(f"健康检查失败: {e}")
        return jsonify({
            "status": "unhealthy",
            "error": str(e),
            "timestamp": time.time()
        }), 500


@app.route('/api/v1/metrics', methods=['GET'])
def get_metrics():
    """获取系统指标（Prometheus格式）"""
    try:
        status = controller.get_system_status()
        
        metrics = []
        
        # 系统指标
        system = status.get('system', {})
        metrics.append(f"hai_system_running {1 if system.get('running') else 0}")
        metrics.append(f"hai_system_uptime {system.get('uptime', 0)}")
        
        # 队列指标
        queue = status.get('queue', {})
        metrics.append(f"hai_queue_total_tasks {queue.get('total_tasks_in_queue', 0)}")
        metrics.append(f"hai_queue_active_users {queue.get('active_users', 0)}")
        
        # 服务器指标
        servers = status.get('servers', {})
        metrics.append(f"hai_servers_total {servers.get('total', 0)}")
        metrics.append(f"hai_servers_healthy {servers.get('healthy', 0)}")
        metrics.append(f"hai_servers_available {servers.get('available', 0)}")
        metrics.append(f"hai_servers_utilization_rate {servers.get('utilization_rate', 0)}")
        
        # 任务指标
        tasks = status.get('tasks', {})
        metrics.append(f"hai_tasks_total {tasks.get('total', 0)}")
        metrics.append(f"hai_tasks_processing {tasks.get('processing', 0)}")
        metrics.append(f"hai_tasks_queued {tasks.get('queued', 0)}")
        metrics.append(f"hai_tasks_completed {tasks.get('completed', 0)}")
        metrics.append(f"hai_tasks_failed {tasks.get('failed', 0)}")
        
        # 统计指标
        statistics = status.get('statistics', {})
        metrics.append(f"hai_stats_total_tasks_processed {statistics.get('total_tasks_processed', 0)}")
        metrics.append(f"hai_stats_total_tasks_successful {statistics.get('total_tasks_successful', 0)}")
        metrics.append(f"hai_stats_total_tasks_failed {statistics.get('total_tasks_failed', 0)}")
        metrics.append(f"hai_stats_total_servers_created {statistics.get('total_servers_created', 0)}")
        metrics.append(f"hai_stats_total_servers_destroyed {statistics.get('total_servers_destroyed', 0)}")
        metrics.append(f"hai_stats_total_scaling_actions {statistics.get('total_scaling_actions', 0)}")
        
        response_text = '\n'.join(metrics)
        
        return Response(
            response_text,
            mimetype='text/plain; version=0.0.4; charset=utf-8'
        )
        
    except Exception as e:
        logger.error(f"获取指标失败: {e}")
        return jsonify({
            "error": str(e)
        }), 500


@app.errorhandler(404)
def not_found(error):
    """404错误处理"""
    return jsonify({
        "success": False,
        "error": "API端点不存在"
    }), 404


@app.errorhandler(405)
def method_not_allowed(error):
    """405错误处理"""
    return jsonify({
        "success": False,
        "error": "HTTP方法不被允许"
    }), 405


@app.errorhandler(500)
def internal_error(error):
    """500错误处理"""
    return jsonify({
        "success": False,
        "error": "内部服务器错误"
    }), 500


def create_app():
    """创建Flask应用"""
    return app


if __name__ == "__main__":
    # 设置日志
    logging.basicConfig(
        level=logging.INFO,
        format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
    )
    
    # 启动应用
    app.run(
        host='0.0.0.0',
        port=CONFIG['system'].get('api_port', 8080),
        debug=CONFIG['system'].get('debug_mode', False)
    )
